package tech

import "ssp/set"

var SUBSET_NAMES = []string{"Pair", "Triple", "Quadruple"}

func (g *Grid) nakedHouse(house *House, nakedCount int) (used bool, results []*Result) {
	//fmt.Println("nakedHouse", strHouse(&house))
	unSolvedCells := getUnsolvedCells(house.cells[:])
	for _, cells := range combine(unSolvedCells, nakedCount) {
		nakedCands := set.NewSet()
		for _, cell := range cells {
			nakedCands = nakedCands.Union(cell.cands)
		}
		if nakedCands.Count() != nakedCount {
			continue
		}
		ok, rmCells := g.canRemoveSeenCands(nakedCands, cells)
		if ok {
			used = true
			if OUTPUTRESULT {
				result := new(Result)
				result.addRemoved(nakedCands, rmCells)
				result.addHelpHouses([]*House{house})
				group := result.getHelpCandsGroup()
				group.add(nakedCands, cells)
				result.setStrategyName(house.KindName() + " Naked " + SUBSET_NAMES[nakedCount-2])
				results = append(results, result)
			}
			if CHANGE {
				removeCands(nakedCands, rmCells)
			}
			if !EXHAUSTIVE {
				return
			}
		}
	}
	return
}

/*
func canClearupNaked(cands set.Set, nakedCells, unSolvedCells []*Cell) (

		ok bool, rmCells []*Cell) {
		for _, cell := range unSolvedCells {
			if !cell.isMemberOf(nakedCells) && cell.canRemoveCands(cands) {
				rmCells = append(rmCells, cell)
				ok = true
			}
		}
		return
	}
*/
func (g *Grid) NakedPairHouse(house *House) (bool, []*Result) {
	return g.nakedHouse(house, 2)
}

func (s *Solve) NakedPair(g *Grid) (bool, []*Result) {
	return g.useTechInAllHouse(g.NakedPairHouse)
}

func (g *Grid) NakedTripleHouse(house *House) (bool, []*Result) {
	return g.nakedHouse(house, 3)
}

func (s *Solve) NakedTriple(g *Grid) (bool, []*Result) {
	return g.useTechInAllHouse(g.NakedTripleHouse)
}

func (g *Grid) NakedQuadrupleHouse(house *House) (bool, []*Result) {
	return g.nakedHouse(house, 4)
}

func (s *Solve) NakedQuadruple(g *Grid) (bool, []*Result) {
	return g.useTechInAllHouse(g.NakedQuadrupleHouse)
}

func (g *Grid) canRemoveSeenCands(cands set.Set, cells []*Cell) (used bool, rmCells []*Cell) {
	shares := g.seenCells(cells[0])
	for _, cell := range cells[1:] {
		shares = shareCells(shares, g.seenCells(cell))
	}

	for _, cell := range shares {
		if cell.canRemoveCands(cands) {
			rmCells = append(rmCells, cell)
			used = true
		}
	}
	return
}
